package com.example.jiugongge;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by qw on 2017/3/4.
 */

public class NineView extends View {
    private Bitmap mBitmapDDOrigin;
    private Bitmap mBitmapDDClicked;
    private Bitmap mBitmapDDLine;
    private Bitmap mBitmapDDArrow;
    private final float DDBS = 2.4f;
    private float mDDDistance;
    private float mDDRadius;
    private float mLineHeightHalf,mLineWidth;
    private MyPointer mPointerNineLT[][] = new MyPointer[3][3];
    private MyPointer mPointerNineCenter[][] = new MyPointer[3][3];
    private float mScreenCenterX, mScreenCenterY;
    private Paint mPaint;
    private MyPointer mPointerEvent=new MyPointer(0,0);
    private Matrix mMatrix=new Matrix();
    private List<MyPointer> mMyPointersChecked=new ArrayList<>();
    private List<MyPointer> mMyPointersCheckedCenter=new ArrayList<>();
    private  int mIndex1=-1,mIndex2=-1;
    public NineView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        mBitmapDDOrigin = BitmapFactory.decodeResource(this.getResources(), R.drawable.locus_round_original);
        mBitmapDDClicked = BitmapFactory.decodeResource(this.getResources(), R.drawable.locus_round_click);
        mBitmapDDLine = BitmapFactory.decodeResource(this.getResources(), R.drawable.locus_line);
        mBitmapDDArrow = BitmapFactory.decodeResource(this.getResources(), R.drawable.locus_arrow);
        mDDRadius = mBitmapDDOrigin.getWidth() / 2.0f;
        mLineHeightHalf=mBitmapDDLine.getHeight()/2.0f;
        mLineWidth=mBitmapDDLine.getWidth();
        mDDDistance = mDDRadius * DDBS;
        mScreenCenterX = getResources().getDisplayMetrics().widthPixels / 2.0f;
        mScreenCenterY = getResources().getDisplayMetrics().heightPixels / 2.0f;
        initNineDDLT();
        initNineDDCenter();
    }

    private void initNineDDCenter() {
        mPointerNineCenter[0][0] = new MyPointer(mScreenCenterX -mDDDistance, mScreenCenterY -mDDDistance);
        mPointerNineCenter[0][1] = new MyPointer(mScreenCenterX , mScreenCenterY -mDDDistance);
        mPointerNineCenter[0][2] = new MyPointer(mScreenCenterX +mDDDistance, mScreenCenterY -mDDDistance);

        mPointerNineCenter[1][0] = new MyPointer(mScreenCenterX -mDDDistance, mScreenCenterY );
        mPointerNineCenter[1][1] = new MyPointer(mScreenCenterX , mScreenCenterY );
        mPointerNineCenter[1][2] = new MyPointer(mScreenCenterX +mDDDistance, mScreenCenterY );

        mPointerNineCenter[2][0] = new MyPointer(mScreenCenterX -mDDDistance, mScreenCenterY +mDDDistance);
        mPointerNineCenter[2][1] = new MyPointer(mScreenCenterX , mScreenCenterY  + mDDDistance);
        mPointerNineCenter[2][2] = new MyPointer(mScreenCenterX +mDDDistance, mScreenCenterY +mDDDistance);
    }


    private void initNineDDLT() {

        mPointerNineLT[0][0] = new MyPointer(mScreenCenterX - mDDRadius-mDDDistance, mScreenCenterY - mDDRadius-mDDDistance);
        mPointerNineLT[0][1] = new MyPointer(mScreenCenterX - mDDRadius, mScreenCenterY - mDDRadius-mDDDistance);
        mPointerNineLT[0][2] = new MyPointer(mScreenCenterX - mDDRadius+mDDDistance, mScreenCenterY - mDDRadius-mDDDistance);

        mPointerNineLT[1][0] = new MyPointer(mScreenCenterX - mDDRadius-mDDDistance, mScreenCenterY - mDDRadius);
        mPointerNineLT[1][1] = new MyPointer(mScreenCenterX - mDDRadius, mScreenCenterY - mDDRadius);
        mPointerNineLT[1][2] = new MyPointer(mScreenCenterX - mDDRadius+mDDDistance, mScreenCenterY - mDDRadius);

        mPointerNineLT[2][0] = new MyPointer(mScreenCenterX - mDDRadius-mDDDistance, mScreenCenterY - mDDRadius+mDDDistance);
        mPointerNineLT[2][1] = new MyPointer(mScreenCenterX - mDDRadius, mScreenCenterY - mDDRadius + mDDDistance);
        mPointerNineLT[2][2] = new MyPointer(mScreenCenterX - mDDRadius+mDDDistance, mScreenCenterY - mDDRadius+mDDDistance);



    }

    //画9个基本点
    private void drawNineDDLT(Canvas canvas) {
        for (MyPointer[] myPointers:mPointerNineLT){
            for (MyPointer mPointer:myPointers){
                Bitmap bitmap=null;
                if (mPointer.state==MyPointer.STATE_ORIGINAL){
                    bitmap=mBitmapDDOrigin;
                }else {
                    bitmap=mBitmapDDClicked;
                }
                canvas.drawBitmap(bitmap,mPointer.x,mPointer.y,mPaint);
            }

        }
    }
    //判断某个点是否在某个蛋蛋范围内，返回此触发点所在蛋蛋
    private  MyPointer pointerIsInDD(MyPointer pointer){
        for (int i=0;i<3;i++){
            for (int j=0;j<3;j++){
                double distance=caculatorDistance(pointer,mPointerNineCenter[i][j]);
                if (distance<=mDDRadius){
                    mIndex1=i;
                    mIndex2=j;
                    return  mPointerNineCenter[i][j];
                }
            }
        }
        return null;
    }

    /**
     * 计算两点间的距离
     *
     * @param pointerFrom
     * @param pointerTo
     * @return
     */
    private double caculatorDistance(MyPointer pointerFrom, MyPointer pointerTo) {

        return Math.sqrt((pointerFrom.x-pointerTo.x)*(pointerFrom.x-pointerTo.x)+(pointerFrom.y-pointerTo.y)*(pointerFrom.y-pointerTo.y));
    }

    /**
     * 画一条线
     */
    private void drawOneLine(Canvas canvas,MyPointer myPointerFrom, MyPointer myPointerTo) {
        float xCenter=myPointerFrom.x;
        float yCenter=myPointerFrom.y;
        //1.线的位置
        mMatrix.postTranslate(xCenter,yCenter-mLineHeightHalf);
//        //3.线的长短
        mMatrix.postScale(caculatorScale(myPointerFrom,myPointerTo),1f,xCenter,yCenter);
//        //2.线的方向
        mMatrix.postRotate((float) caculatorDegrees(myPointerFrom,myPointerTo),xCenter,yCenter);

        canvas.drawBitmap(mBitmapDDLine,mMatrix,mPaint);
        //重置，保证每次的效果不会叠加
        mMatrix.reset();
    }

    private float caculatorScale(MyPointer myPointerFrom, MyPointer myPointerTo) {

        double distance = caculatorDistance(myPointerFrom, myPointerTo);
        return (float) (distance/mLineWidth);
    }

    private double caculatorDegrees(MyPointer myPointerFrom, MyPointer myPointerTo) {
        float xFrom=myPointerFrom.x;
        float yFrom=myPointerFrom.y;
        float xTo=myPointerTo.x;
        float yTo=myPointerTo.y;

        if (xFrom<=xTo && yFrom==yTo){
            return 0;
        }
        if (xFrom>xTo && yFrom==yTo){
            return  180;
        }
        if (xFrom==xTo && yFrom<yTo){
            return  90;
        }
        if (xFrom==xTo && yFrom>yTo){
            return  270;
        }

        double tanValue=Math.abs(yFrom-yTo)/Math.abs(xFrom-xTo);

        double atanValue=Math.toDegrees(Math.atan(tanValue));

        if (yTo>yFrom){
            if (xFrom>xTo){
                //2
                return  180-atanValue;
            }else {
                //1
                return atanValue;
            }
        }else {
            if (xFrom>xTo){
                //3
                return  180+atanValue;
            }else {
                //4
                return  360-atanValue;
            }

        }
    }

    /**
     * 重置界面效果
     */
    private void reset() {
        for (MyPointer myPointer:mMyPointersChecked){
            myPointer.state=MyPointer.STATE_ORIGINAL;
        }

        mMyPointersChecked.clear();
        mMyPointersCheckedCenter.clear();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        drawNineDDLT(canvas);
        if (mMyPointersCheckedCenter .size()!=0) {
            drawAllLines(canvas);
        }

    }

    private void drawAllLines(Canvas canvas) {
        MyPointer myPointerFrom=mMyPointersCheckedCenter.get(0);

        for (int i=1;i<mMyPointersCheckedCenter.size();i++){

            MyPointer myPointerTo=mMyPointersCheckedCenter.get(i);
            drawOneLine(canvas,myPointerFrom,myPointerTo);
            myPointerFrom=myPointerTo;
        }

        drawOneLine(canvas,mMyPointersCheckedCenter.get(mMyPointersCheckedCenter.size()-1),mPointerEvent);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                mPointerEvent.x=event.getX();
                mPointerEvent.y=event.getY();
                MyPointer myPointer= pointerIsInDD(mPointerEvent);
                if (myPointer != null) {
                    //1.该状态
                    mPointerNineLT[mIndex1][mIndex2].state=MyPointer.STATE_CLICKED;
                    //2.记录每一个选中的蛋蛋的左上角，判断去重
                    if (!mMyPointersChecked.contains(mPointerNineLT[mIndex1][mIndex2])){
                        mMyPointersChecked.add(mPointerNineLT[mIndex1][mIndex2]);
                    }
                    //3..记录每一个选中的蛋蛋的左上角圆心点，判断去重
                    if (!mMyPointersCheckedCenter.contains(mPointerNineCenter[mIndex1][mIndex2])){
                        mMyPointersCheckedCenter.add(mPointerNineCenter[mIndex1][mIndex2]);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                reset();
                break;


        }

        invalidate();
        return true ;
    }


    private class MyPointer {

        public static final int STATE_ORIGINAL = 110;
        public static final int STATE_CLICKED = 120;
        public float x, y;
        public int state = STATE_ORIGINAL;



        public MyPointer(float x, float y) {
            this.x = x;
            this.y = y;
        }


        public boolean equals(MyPointer other) {
//            if (this.x==other.x&&this.y==other.y){
//                return true
//            }else {
//                return false
//            }
            return  this.x==other.x&&this.y==other.y;
        }

    }
}
